home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TeX 1995 July
/
TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO
/
macros
/
latex209
/
contrib
/
slatex
/
funval.cl
< prev
next >
Wrap
Lisp/Scheme
|
1993-11-07
|
4KB
|
142 lines
;funval.cl
;makes CL treatment of functions and applications like Scheme's
;(c) Dorai Sitaram, December 1991, Rice University
;advantage:
;no funcalls or #'s needed, ever
(progn
;don't load this file twice
(when (fboundp 'letrec) (error "loading funval.cl twice!"))
;print in lower case, since upper case ruins your eyes
(setq *print-case* :downcase))
(progn
;make all identifiers with symbol-functions also have the function
;as their symbol value
(do-all-symbols (x)
(cond ((boundp x) 'void)
((macro-function x) 'void)
((special-form-p x) 'void)
((fboundp x) (setf (symbol-value x) (symbol-function x))))))
(defun insert-funcalls (e &optional bvs)
;insert funcalls appropriately in the expression e
(if (not (consp e)) e
(let ((a (car e)))
(cond
((and (consp a) (eq (car a) 'lambda))
(mapcar (function (lambda (e1) (insert-funcalls e1 bvs)))
e))
((or (not (symbolp a)) (member a bvs :test (function eq)))
(cons 'funcall
(mapcar (function (lambda (e1) (insert-funcalls e1 bvs)))
e)))
((eq a 'lambda)
(let* ((new-bvs (cadr e))
(ext-bvs (append new-bvs bvs)))
`(lambda ,new-bvs
,@(mapcar (function
(lambda (e1)
(insert-funcalls e1 ext-bvs)))
(cddr e)))))
((eq a 'quote) e)
((eq a 'function)
(let ((d (insert-funcalls (cadr e) bvs)))
(if (and (consp d) (eq (car d) 'function))
d (list 'function d))))
((eq a 'setq)
`(setq ,(cadr e) ,(insert-funcalls (caddr e) bvs)))
((eq a 'let)
(let* ((new-bvs (mapcar (function car) (cadr e)))
(ext-bvs (append new-bvs bvs)))
`(let
,(mapcar (function
(lambda (x.i)
(let ((x (car x.i)) (i (cadr x.i)))
`(,x ,(insert-funcalls i bvs)))))
(cadr e))
,@(mapcar (function
(lambda (e1)
(insert-funcalls e1 ext-bvs)))
(cddr e)))))
((eq a 'let*)
(let ((x.i* (cadr e)) (x.ii* '()))
(loop (if (null x.i*)
(return
`(let* ,(reverse x.ii*)
,@(mapcar (function
(lambda (e1)
(insert-funcalls e1 bvs)))
(cddr e))))
(let* ((x.i (car x.i*))
(x (car x.i)) (i (cadr x.i)))
(setq x.i* (cdr x.i*))
(setq x.ii*
(cons (list x (insert-funcalls i bvs))
x.ii*))
(setq bvs (cons x bvs)))))))
((eq a 'eval-when)
`(eval-when ,(cadr e)
,@(mapcar (function
(lambda (e1)
(insert-funcalls e1 bvs))) (cddr e))))
((macro-function a)
(insert-funcalls (macroexpand e) bvs))
((special-form-p a)
(mapcar (function
(lambda (e1) (insert-funcalls e1 bvs)))
e))
(t ;i.e. is a (potential) symbol function
(cons a
(mapcar (function (lambda (e1) (insert-funcalls e1 bvs)))
(cdr e))))))))
(progn
;change eval to call insert-funcalls
(unless (fboundp 'common-lisp-eval)
(setf (symbol-function 'common-lisp-eval) (function eval))
(setq *evalhook*
(function
(lambda (form env)
(common-lisp-eval (insert-funcalls form)))))))
(defun insert-rest (xx)
;change the ". z" format of scheme lambda to
;the "&rest z" format of cl lambda
(let ((yy '()))
(loop
(cond ((null xx) (return))
((symbolp xx)
(setq yy (cons xx (cons '&rest yy))) (return))
((consp xx)
(setq yy (cons (car xx) yy))
(setq xx (cdr xx)))
(t (error "insert-rest"))))
(nreverse yy)))
(eval-when (compile load eval)
;cl lambda will clash with new lambda, so shadow it
(shadow 'lambda))
(defmacro lambda (v . z)
;install our new scheme lambda
`(function
(lisp:lambda
,(insert-rest v)
,@z)))
(defmacro define (x . z)
;scheme-like define
(cond ((consp x)
`(define ,(car x) (lambda ,(cdr x) ,@z)))
((and (symbolp x) (null (cdr z)))
(let ((v (car z)))
`(progn
(setq ,x ,v)
(when (functionp ,x) (setf (symbol-function ',x) ,x))
(values))))
(t (error "define ~s" x))))
; end funval.cl